import os, sys, string, re

def fatal(line, msg):
    sys.stderr.write("error: %d: %s\n" % (line, msg))
    sys.exit(1)

if not len(sys.argv) == 2:
    fatal(0, "usage: mktable.py infile.c")

table_name = "tbl_" + sys.argv[1][:-2]
fdi = open(sys.argv[1], "r")
fdo = open("tbl_" + sys.argv[1], "w")

pattern = re.compile("^\s*(void)*\s*(cmd_[a-zA-z0-9_]+)\s*\((.*?)\)\s*(//.*)?$")
lineno = 0

parampattern = re.compile("^\s*([a-zA-Z][a-zA-Z0-9]*)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*$")

table = ""

fdo.write('/* autogenerated by mktable.py -- do not edit */\n\n')
fdo.write('\n#include "debugger.h"\n')

for line in fdi.xreadlines():
    
    match = pattern.match(line)
    lineno = lineno + 1
    if not match:
        continue

    name = match.group(2)
    shortname = name[4:]
    args = match.group(3).strip()
    comment = match.group(4)
    if comment:
        comment = comment[2:].strip()
    else:
        comment = ""

    parts = args.split(',')
    arglist = []
    namelist = []
    
    for part in parts:
        part = part.strip()
        if not part:
            continue

        argmatch = parampattern.match(part)
        if not argmatch:
            fatal(lineno, "cannot parse parameters '%s'" % part)
            
        atype = argmatch.group(1)
        aname = argmatch.group(2)

        if not atype in ('Address', 'Value', 'String'):
            fatal(lineno, "unknown type '%s'" % part)

        arglist.append(atype)
        namelist.append(aname)
        
    table += '    { "%s", _%s, "%s" },\n' % (shortname, name, comment)

    decl = "void %s(" % name
    number = 0
    for atype in arglist:
        if number != 0:
            decl += ", "
        decl += atype
        number = number + 1
    decl += ");"

    fdo.write(decl + "\n")
    fdo.write("static void _%s(int argc, const char **argv)\n" % name)
    fdo.write("{\n")

    if len(arglist):
        fdo.write('    if(argc < %d) {\n        ERROR("not enough arguments");\n        return;\n    }\n' % len(arglist))
        
    call = "    %s(" % name
    
    number = 0
    for atype in arglist:
        if number != 0:
            call += ","
        call += "\n        arg_to_%s(argv[%d])" % (atype, number)
        number = number + 1
    call += ");\n"
    fdo.write(call)
        
    fdo.write("}\n\n")

fdo.write("Command %s[] = {\n" % table_name)
fdo.write(table + "    { 0, 0, 0 },\n")
fdo.write("};\n")
